package yunjiao.javatutorials.guava.concurrent;

import com.google.common.util.concurrent.Striped;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.ReadWriteLock;

/**
 * 基于特定标识（如 ID、键值）进行并发控制的场景
 *
 * @author yangyunjiao
 */
public class StripedReadWriteLockExample {
    // 创建包含 64 个条纹的读写锁
    private static final Striped<ReadWriteLock> stripedLocks = Striped.readWriteLock(64);

    // 模拟用户数据存储
    private static final ConcurrentMap<String, String> userData = new ConcurrentHashMap<>();

    // 读写用户数据
    public static void updateUser(String userId, String data) {
        ReadWriteLock lock = stripedLocks.get(userId);
        lock.writeLock().lock();
        try {
            userData.put(userId, data);
            System.out.println(Thread.currentThread().getName() + " 更新用户 " + userId + " 的数据: " + data);
        } finally {
            lock.writeLock().unlock();
        }
    }

    public static String readUser(String userId) {
        ReadWriteLock lock = stripedLocks.get(userId);
        lock.readLock().lock();
        try {
            String data = userData.get(userId);
            System.out.println(Thread.currentThread().getName() + " 读取用户 " + userId + " 的数据: " + data);
            return data;
        } finally {
            lock.readLock().unlock();
        }
    }

    // 测试代码
    public static void main(String[] args) throws InterruptedException {
        // 模拟并发读写
        Thread writer1 = new Thread(() -> updateUser("user1", "Data1"));
        Thread writer2 = new Thread(() -> updateUser("user1", "Data2")); // 同一用户，写写互斥
        Thread reader1 = new Thread(() -> readUser("user1"));
        Thread reader2 = new Thread(() -> readUser("user1")); // 同一用户，读读不互斥

        writer1.start();
        writer2.start();
        reader1.start();
        reader2.start();

        writer1.join();
        writer2.join();
        reader1.join();
        reader2.join();

    }
}
